﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web.Mvc;
using System.Web.UI;
using DevExpress.Web.ASPxEditors;
using DevExpress.Web.ASPxUploadControl;
using DevExpress.Web.Mvc;
using Dogshow.BusinessLogic.Managers;
using Dogshow.Model;
using Dogshow.Web.Infrastructure;
using Dogshow.Web.Models;
using Dogshow.Web.Services;
using Dogshow.Web.Settings;
using Dogshow.Web.ViewModels.Psi;
using DogshowRepository;
using Ninject;
using ValidationSettings = DevExpress.Web.ASPxUploadControl.ValidationSettings;
using Dogshow.Web.Helpers;

namespace Dogshow.Web.Controllers
{
    public class PsiController : DogshowController
    {
        private readonly IRepoServices m_RepoService;

        private readonly PasManager m_PasManager;

        private readonly KorisniciManager m_KorisniciManager;

        public static ValidationSettings ImageValidationSettings = new ValidationSettings
        {
            NotAllowedFileExtensionErrorText = "Dozvoljene su jpg i png slike",
            AllowedFileExtensions = new[] { ".jpg", ".jpeg", ".png" },
            MaxFileSize = 500 * 1024,
            MaxFileSizeErrorText = "Maksimalno dozvoljena veličina slike je 500 kB",
            ShowErrors = true
        };

        private const string ImageDir = "/Slike/Psi/";

        public PsiController(IRepoServices mRepoService, PasManager pasManager, KorisniciManager korisniciManager)
        {
            m_RepoService = mRepoService;
            m_PasManager = pasManager;
            m_KorisniciManager = korisniciManager;
        }

        public ActionResult Index()
        {
            var psi = m_RepoService.VratiPse();
            HttpContext.Application["Psi"] = psi;
            ViewBag.Psi = psi;
            return View(new Pas());
        }

        public PartialViewResult PasCallbackPanelCallback(int id)
        {
            var pas = m_RepoService.VratiPsa(id.ToString());
            return PartialView("_PasCallbackPanel", pas);
        }

        public PartialViewResult PsiGridViewCallback()
        {
            ViewBag.Psi = HttpContext.Application["Psi"];
            return PartialView("_PsiGridView", ViewBag.Psi);
        }

        public JsonResult PostojiRodovnik(string id, string rodovnik)
        {
            return Json(new {HasError = m_RepoService.PostojiPas(rodovnik, id)});
        }

        public PartialViewResult RasePasaComboBoxCallback()
        {
            return PartialView("_RasePasaComboBox", null);
        }

        public PartialViewResult VlasnikPsaComboBox()
        {
            ViewData["settings"] = PodesavanjaComboBoxaVlasnikaPsa();
            return PartialView("_KinologComboBox");
        }

        public PartialViewResult OdgajivacPsaComboBox()
        {
            ViewData["settings"] = PodesavanjaComboBoxaOdgajivacaPsa();
            return PartialView("_KinologComboBox");
        }

        public PartialViewResult OdgajivacComboBox()
        {
            return PartialView("_OdgajivacComboBox");
        }

        public ActionResult SacuvajSlikuPsa()
        {
            UploadControlExtension.GetUploadedFiles("Upload", ImageValidationSettings, OnFileUpload);
            return null;
        }

        private void OnFileUpload(object sender, FileUploadCompleteEventArgs e)
        {
            if (!e.IsValid)
            {
                e.ErrorText = "Slanje slike nije uspelo";
                return;
            }
            var dir = Server.MapPath(ImageDir);
            var ext = Path.GetExtension(e.UploadedFile.FileName);
            var newImageName = Guid.NewGuid() + ext;
            var file = Path.Combine(dir, newImageName);
            e.UploadedFile.SaveAs(file);
            var urlResolver = sender as IUrlResolutionService;
            if (urlResolver != null)
            {
                string url = urlResolver.ResolveClientUrl(Path.Combine(ImageDir, newImageName));
                e.CallbackData = url;
            }
        }

        public JsonResult DodajKinologa([ModelBinder(typeof(DevExpressEditorsBinder))]Kinolog kinolog)
        {
            if (!ModelState.IsValid)
            {
                return Json(new { Success = false, });
            }
            var kinoloziRepository = ((IKernel)Bootstrap.Bootstrapper.Container).Get<IKinoloziRepository>();
            var mestaRepository = ((IKernel)Bootstrap.Bootstrapper.Container).Get<IMestaRepository>();
            var id = kinoloziRepository.DodajIVratiId(kinolog);
            if (kinolog.IdMesta != null)
            {
                var mesto = mestaRepository.VratiPoId(kinolog.IdMesta.Value);
                kinolog.Mesto = mesto;
            }
            kinolog.Id = id;
            return Json(new {Success = true, Item = kinolog});
        }

        public static object FiltrirajRase(ListEditItemsRequestedByFilterConditionEventArgs arg)
        {
            var repos = ((IKernel) Bootstrap.Bootstrapper.Container).Get<IRaseRepository>();
            var rase = repos.FiltrirajPoDeluNaziva(arg.Filter, arg.BeginIndex, arg.EndIndex);
            return rase;
        }

        public static object FiltrirajRasuPoId(ListEditItemRequestedByValueEventArgs args)
        {
            if (args.Value == null) return null;
            var id = Convert.ToInt32(args.Value);
            var repos = ((IKernel)Bootstrap.Bootstrapper.Container).Get<IRaseRepository>();
            return repos.VratiPoId(id);
        }

        public static object FiltrirajPsePoBrojuRodovnika(ListEditItemsRequestedByFilterConditionEventArgs arg)
        {
            var repos = ((IKernel)Bootstrap.Bootstrapper.Container).Get<IPsiRepository>();
            return repos.FiltrirajPoBrojuRodovnika(arg.Filter, arg.BeginIndex, arg.EndIndex);
        }

        public static object FiltrirajPsePoId(ListEditItemRequestedByValueEventArgs args)
        {
            return Enumerable.Empty<Pas>();
        }

        public JsonResult VratiPse()
        {
            var psi = m_PasManager.VratiSvePse();
            return Json(psi, JsonRequestBehavior.AllowGet);
        }

        public static IEnumerable<Pas> VratiPsaPoId(int? id)
        {
            if (!id.HasValue) return Enumerable.Empty<Pas>();
            var repos = ((IKernel)Bootstrap.Bootstrapper.Container).Get<IPsiRepository>();
            return new[] {repos.VratiPoId(id.Value)};
        }

        public PartialViewResult OtacPsaComboBoxCallback()
        {
            var podesavanja = PodesavanjeComboBoxaZaOcaPsa();
            ViewData["settings"] = podesavanja;
            return PartialView("_PasComboBox");
        }

        public PartialViewResult MajkaPsaComboBoxCallback()
        {
            var podesavanja = PodesavanjeComboBoxaZaMajku();
            ViewData["settings"] = podesavanja;
            return PartialView("_PasComboBox");
        }

        public static IEnumerable<RasaPsa> VratiRasuPoId(int? idRase)
        {
            if (idRase == null) return new RasaPsa[0];
            var repos = ((IKernel)Bootstrap.Bootstrapper.Container).Get<IRaseRepository>();
            var rasa = repos.VratiPoId(idRase.Value);
            if (rasa != null) return new[] {rasa};
            return new RasaPsa[0];
        }

        [HttpPost]
        public ActionResult AzurirajPsa([ModelBinder(typeof(DevExpressEditorsBinder))]Pas pas)
        {
            if (m_RepoService.PostojiPas(pas.BrojRodovnika, pas.Id.ToString()))
            {
                ModelState.AddModelError("BrojRodovnika", "Broj rodovnika već postoji");
            }
            if (!ModelState.IsValid)
            {
                ViewBag.Psi = HttpContext.Application["Psi"];
                return View("Index", pas);
            }
            m_RepoService.SacuvajPsa(pas);
            return RedirectToAction("Index");
        }

        public ActionResult MojiPsi()
        {
            var korisnik = Request.Cookies.VratiKorisnika();
            var psiKorisnika = m_PasManager.VratiOmiljenePseKorisnika(korisnik.KorisnickoIme);
            var model = new MojiPsiViewModel {NoviUnosLink = Url.Action("UnosPsa", "Psi"), MojiPsi = psiKorisnika};
            return View(model);
        }

        public ActionResult UnosPsa()
        {
            var korisnik = m_KorisniciManager.VratiKorisnikaPoKorisnickomImenu(Request.Cookies.VratiKorisnika().KorisnickoIme);
            PodesavanjeComboBoxaZaOcaPsa();
            PodesavanjeComboBoxaZaMajku();
            PodesavanjaComboBoxaVlasnikaPsa();
            PodesavanjaComboBoxaOdgajivacaPsa();
            return View(new Pas(){IdVlasnika = korisnik.IdKinologa});
        }

        public ActionResult DetaljiPsa(int? id) 
        {
            if (!id.HasValue)
            {
                return RedirectToAction("UnosPsa");
            }
            var pas = m_PasManager.VratiPsa(id.Value);
            PodesavanjeComboBoxaZaOcaPsa();
            PodesavanjeComboBoxaZaMajku();
            PodesavanjaComboBoxaVlasnikaPsa();
            PodesavanjaComboBoxaOdgajivacaPsa();
            return View(pas);
        }

        [HttpPost]
        public ActionResult SacuvajPsa(Pas pas)
        {
            if (!ModelState.IsValid)
            {
                DodajStatus(new PodaciNisuValidni());
                var view = pas.Id == 0 ? "UnosPsa" : "DetaljiPsa";
                PodesavanjeComboBoxaZaOcaPsa();
                PodesavanjeComboBoxaZaMajku();
                PodesavanjaComboBoxaVlasnikaPsa();
                PodesavanjaComboBoxaOdgajivacaPsa();
                return View(view, pas);
            }
            m_PasManager.SacuvajPsa(pas);
            DodajStatus(new UspenoSnimanje());
            return RedirectToAction("DetaljiPsa", pas.Id);
        }

        public ActionResult SacuvajMogPsa(Pas pas)
        {
            if (!ModelState.IsValid)
            {
                DodajStatus(new PodaciNisuValidni());
                return View("DetaljiPsa", pas);
            }
            try
            {
                m_PasManager.SacuvajOmiljenogPsa(pas, Request.Cookies.VratiKorisnika().KorisnickoIme);
                DodajStatus(new UspenoSnimanje());
                return RedirectToAction("DetaljiPsa", pas.Id);
            }
            catch (Exception exc)
            {
                DodajStatus(new Greska(exc));
                return View("DetaljiPsa", pas);
            }
        }

        private PasComboBoxSettings PodesavanjeComboBoxaZaOcaPsa()
        {
            var settings = new PasComboBoxSettings
                               {
                                   Name = "IdOca", 
                                   CallbackRouteValues = new { Controller = "Psi", Action = "OtacPsaComboBoxCallback" },
                                   ButtonClick = "pasComboBoxButtonClick"
                               };
            ViewData["OtacPsaComboBoxSettings"] = settings;
            return settings;
        }

        private PasComboBoxSettings PodesavanjeComboBoxaZaMajku()
        {
            var settings = new PasComboBoxSettings
                               {
                                   Name = "IdMajke", 
                                   CallbackRouteValues = new { Controller = "Psi", Action = "MajkaPsaComboBoxCallback" },
                                   ButtonClick = "pasComboBoxButtonClick"
                               };
            ViewData["MajkaPsaComboBoxSettings"] = settings;
            return settings;
        }

        private KinologComboBoxSettings PodesavanjaComboBoxaVlasnikaPsa()
        {
            var settings = new KinologComboBoxSettings
                               {
                                   Name = "IdVlasnika",
                                   CallbackRouteValues = new {Controller = "Psi", Action = "VlasnikPsaComboBox"},
                                   ButtonClick = "otvoriUnosKinologa"
                               };
            ViewBag.PodesavanjaComboBoxaVlasnikaPsa = settings;
            return settings;
        }

        private KinologComboBoxSettings PodesavanjaComboBoxaOdgajivacaPsa()
        {
            var settings = new KinologComboBoxSettings
            {
                Name = "IdOdgajivaca",
                CallbackRouteValues = new { Controller = "Psi", Action = "OdgajivacPsaComboBox" },
                ButtonClick = "otvoriUnosKinologa"
            };
            ViewBag.PodesavanjaComboBoxaOdgajivacaPsa = settings;
            return settings;
        }
    }
}
